<?php 

class Diccionario {

   private $identificador;
   private $nombre;
   private $categoria;
   private $ambito;
   private $definicion;
   private $rutaXML = "datos/diccionario.xml";
   private $xml;
   private $acepcion = Array('colombia'=>'',
                             'venezuela'=>'',
                             'ecuador'=>'',
                             'peru'=>'');
   private $ejemplo = Array('colombia'=>'',
                             'venezuela'=>'',
                             'ecuador'=>'',
                             'peru'=>'');
   private $fuente = Array('colombia'=>'',
                             'venezuela'=>'',
                             'ecuador'=>'',
                             'peru'=>'');
   
   public function __construct($datos=Array())
   {
      # COLOCAMOS LOS DATOS EN LAS PROPIEDADES DE LA CLASE
      if(isset($datos['identificador']))
        $this->identificador = $datos['identificador'];
        
      if(isset($datos['nombre']))
        $this->nombre =  $datos['nombre'];
      
      if(isset($datos['categoria']))
        $this->categoria =  $datos['categoria'];
      
      if(isset($datos['ambito']))
        $this->ambito =  $datos['ambito'];
      
      //if(isset($datos['clave']) && is_array($datos['clave']))
      //  $this->clave =  $datos['clave'];
      
      if(isset($datos['definicion']))
        $this->definicion =  $datos['definicion'];
        
      foreach($this->acepcion AS $clave => $valor)
      {
        if(isset($datos['acepcion'][$clave]) && !empty($datos['acepcion'][$clave]))
        {
           $this->acepcion[$clave] = $datos['acepcion'][$clave];
        }
      }
      
      foreach($this->ejemplo AS $clave => $valor)
      {
        if(isset($datos['ejemplo'][$clave]) && !empty($datos['ejemplo'][$clave]))
        {
           $this->ejemplo[$clave] = $datos['ejemplo'][$clave];
        }
      }
      
      foreach($this->fuente AS $clave => $valor)
      {
        if(isset($datos['fuente'][$clave]) && !empty($datos['fuente'][$clave]))
        {
           $this->fuente[$clave] = $datos['fuente'][$clave];
        }
      }
      
      $this->cargarXML();
   }
   
   # DEFINIMOS LOS GETs
   public function getNombre()
   {
      return $this->nombre;
   }
   
   public function getCategoria()
   {
      return $this->categoria;
   }
   
   public function getAmbito()
   {
      return $this->ambito;
   }
   
   public function getDefinicion()
   {
      return $this->definicion;
   }
   
   public function getAcepcion()
   {
      return $this->acepcion;
   }
   
   public function getEjemplo()
   {
      return $this->ejemplo;
   }
   
   public function getFuente()
   {
      return $this->fuente;
   }
   
   # DEFINIMOS LOS SETs
   public function setNombre($nombre)
   {
      $this->nombre = $nombre;
   }
   
   public function setCategoria($categoria)
   {
      $this->categoria = $categoria;
   }
   
   public function setAmbito($ambito)
   {
      $this->ambito = $ambito;
   }
   
   public function setDefinicion($definicion)
   {
      $this->definicion = $definicion;
   }
   
   public function setAcepcion($acepcion)
   {
      $this->acepcion = $acepcion;
   }
   
   public function setEjemplo($ejemplo)
   {
      $this->ejemplo = $ejemplo;
   }
   
   public function setFuente($fuente)
   {
      $this->fuente = $fuente;
   }
   
   
   public function ingresar()
   {
   
   
   }
   
   public function detalleRegistro()
   {
      $registros = $this->xml->xpath("registro[@identificador='$this->identificador']");
      
      return $this->getRegistros($registros);
   }
   
   public function listarRegistro()
   {
   
     //ARMAMOS EL WHERE DEPENDIENDO DE LOS VALORES QUE NO ESTÉN VACIOS
     $where = '';
     if(!empty($this->nombre))
       $where = "@nombre='$this->nombre'";
     
     if(!empty($this->ambito))
     {
       $where=(!empty($where)) ? "$where and @clave='$this->ambito'": "ambito[@clave='$this->ambito']";
     }
     
     $resultNombreAmbito = ($where) ? $this->xml->xpath("registro[$where]"):Array();
     $arrayResultAcepcion = Array();
     $flagPais = False;
     foreach($this->acepcion AS $pais => $acepcion)
     {
       if($this->acepcion[$pais])
       {
         $flagPais = True;
         $result = $this->xml->xpath("registro/acepcion[@pais='$pais' and nombre='{$this->acepcion[$pais]}']/parent::*");
       
         if($result)
           $arrayResultAcepcion = array_merge($arrayResultAcepcion,$result);
       }
     }
     
     if(!empty($where) || $flagPais)
     {
       $registros = array_merge($resultNombreAmbito,$arrayResultAcepcion);
       $registros = array_unique($registros);
     }
     else
       $registros = $this->xml->xpath('registro');
     
     $datos = Array();
     $datos = $this->getRegistros($registros);
     
     //Ordenamos el array
     if(count($datos))
       array_multisort($datos,SORT_ASC);
     
     return $datos;
   }
   
   public function salvar()
   {
      # SI HAY UN IDENTIFICADOR PROCEDEMOS A MODIFICAR
      
      
      //PARA MODIFICAR LOS DATOS VAMOS A UTILIZAR TECNOLOGÍA XML
      //EL DOM DE UN DOCUMENTO XML LO PODEMOS MANIPULAR CON LAS API
      //QUE NOS DA PHP
         
      $doc = new DOMDocument();
      $doc->validateOnParse = true;
      $doc->load($this->rutaXML);
      //echo $doc->validate();
         
      #CREAMO UN NUEVO REGISTRO
      $newRegistro = $doc->createElement('registro');
      $newRegistro->setAttribute('nombre',$this->nombre);
      #CREAMOS LOS AMBITOS
      foreach($this->getAmbito() AS $clave => $valor)
      {
         $newAmbito = $doc->createElement('ambito',$valor);
         $newAmbito->setAttribute('clave',$clave);
         $newRegistro->appendChild($newAmbito);
      }
      
      $newCategoria = $doc->createElement('categoria',$this->categoria);
      $newRegistro->appendChild($newCategoria);
      $newDefinicion = $doc->createElement('definicion',$this->definicion);
      $newRegistro->appendChild($newDefinicion);

      foreach($this->acepcion AS $pais => $valor)
      {
         $newAcepcion = $doc->createElement('acepcion');
         $newAcepcion->setAttribute('pais',$pais);
         $newAcepcionNombre = $doc->createElement('nombre',$this->acepcion[$pais]);
         $newAcepcion->appendChild($newAcepcionNombre);
         $newAcepcionEjemplo = $doc->createElement('ejemplo',$this->ejemplo[$pais]);
         $newAcepcion->appendChild($newAcepcionEjemplo);
         $newAcepcionFuente = $doc->createElement('fuente',$this->fuente[$pais]);
         $newAcepcion->appendChild($newAcepcionFuente);
         #
         $newRegistro->appendChild($newAcepcion);
      }
        
      # SI EXISTE EL IDENTIFICADOR SIGNIFICA QUE DEBEMOS MODIFICAR
      if(!empty($this->identificador))
      {
         #$newRegistro->setAttribute('identificador',$this->identificador);
         $registro = $doc->getElementById($this->identificador);
         if($registro)
         {
           $this->identificador = $this->slugify($this->nombre.' '.implode('-',array_keys($this->ambito)));
           $newRegistro->setAttribute('identificador',$this->identificador);
           $registro->parentNode->replaceChild($newRegistro,$registro);
         }
         else
           return false;
      }
      else
      {
        # HACEMOS EL INGRESO
        # Generamos el identificador que esta compuesto del nombre y los ambitos
        $this->identificador = $this->slugify($this->nombre.' '.implode('-',array_keys($this->ambito)));
        
        $newRegistro->setAttribute('identificador',$this->identificador);
        $nodoPrincipal = $doc->getElementsByTagName('diccionario');
        foreach($nodoPrincipal AS $nodo)
          $nodo->appendChild($newRegistro);
      }

      $doc->save($this->rutaXML);
      return true;
   }
   
   public function eliminar()
   {
      $doc = new DOMDocument();
      $doc->validateOnParse = true;
      $doc->load($this->rutaXML);
      $registro = $doc->getElementById($this->identificador);
      $registro->parentNode->removeChild($registro);
      
      $doc->save($this->rutaXML);
      return true;
   }
   
   private function getRegistros(Array $registros)
   {
     foreach($registros as $registro)
     {
       $attsRegistro = $registro->attributes();
       
       //SACAMOS TODOS LOS ELEMENTOS DE acepcion ENCONTRADOS
       $arrayAcepcion = Array();
       foreach($registro->acepcion AS $acepcion)
       {
            $attsAccepcion = $acepcion->attributes();
            //CONCATENEMOS TODAS LAS ETIQUETAS nombre DE LA ACEPCION
            $nombres = "";
            foreach($acepcion->nombre AS $nombre)
              $nombres[] = $nombre;
            
            $ejemplo = trim($acepcion->ejemplo);
            $fuente = trim($acepcion->fuente);
            
            //$arrayAcepcion = array_merge($arrayAcepcion,Array("{$attsAccepcion['pais']}"=>implode(',',$nombres),'ejemplo'=>$ejemplo,'fuente'=>$fuente));
            
            $arrayAcepcion = array_merge($arrayAcepcion,Array("{$attsAccepcion['pais']}"=>Array('acepcion'=>implode(',',$nombres),'ejemplo'=>$ejemplo,'fuente'=>$fuente)));
       }
       
       //SACAMOS TODOS LOS ELEMENTOS DE ambito ENCONTRADOS
       $arrayAmbitos = Array();
       foreach($registro->ambito AS $ambito)
       {
          $attAmbito = $ambito->attributes();
          $arrayAmbitos["{$attAmbito['clave']}"] = (string)$ambito;
       }
       //SACAMOS LOS CAMPOS
       $nombre = (string)$attsRegistro['nombre'];
       $identificador = (string)$attsRegistro['identificador'];
       $categoria = (string)$registro->categoria;
       $definicion = (string)$registro->definicion;
       //$ambitos = implode(',',$arrayAmbitos);
       
       $datos[] = array_merge(Array('nombre'=>$nombre,'definicion'=>$definicion,'categoria'=>$categoria,'ambito'=>$arrayAmbitos,'identificador'=>$identificador),$arrayAcepcion);
       
     }
 
     return $datos;
   }
   
   private function cargarXML()
   {
      $this->xml = simplexml_load_file($this->rutaXML);
   }
   
   
  private function slugify($text)
  {
    // replace all non letters or digits by -
    $text = preg_replace('~[^\\pL\d]+~u', '-', $text);
    // trim and lowercase
    $text = strtolower(trim($text, '-'));   
    return $text;
  }

}

?>